001 /*
002 * Copyright 2005-2006 Stephen J. McConnell.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.metro.info;
020
021 import java.io.Serializable;
022
023 import net.dpml.lang.Version;
024
025 /**
026 * This ServiceDescriptor defines the interface and service version
027 * published by a service instance.
028 *
029 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
030 * @version 1.0.2
031 */
032 public final class ServiceDescriptor implements Serializable
033 {
034 /**
035 * Serial version identifier.
036 */
037 static final long serialVersionUID = 1L;
038
039 /**
040 * The name of service class.
041 */
042 private final String m_classname;
043
044 /**
045 * The version of service class.
046 */
047 private final Version m_version;
048
049 /**
050 * Construct a service with specified type. The type argument will be
051 * parsed for a classname and version in the form [classname]#[version].
052 * If not version is present a default 1.0.0 version will be assigned.
053 *
054 * @param spec the service specification
055 * @exception NullPointerException if the spec is null
056 */
057 public ServiceDescriptor( final String spec ) throws NullPointerException
058 {
059 this( parseClassname( spec ), parseVersion( spec ) );
060 }
061
062 /**
063 * Construct a service with specified name, version.
064 *
065 * @param classname the name of the service
066 * @param version the version of service
067 * @exception NullPointerException if the classname or version is null
068 */
069 public ServiceDescriptor( final String classname, final Version version )
070 throws NullPointerException
071 {
072 if( null == classname )
073 {
074 throw new NullPointerException( "classname" );
075 }
076 if( classname.equals( "" ) )
077 {
078 throw new NullPointerException( "classname" );
079 }
080
081 m_classname = classname;
082
083 if( null == version )
084 {
085 m_version = Version.parse( "1" );
086 }
087 else
088 {
089 m_version = version;
090 }
091 }
092
093 /**
094 * Return classname of service specification.
095 *
096 * @return the classname of the service specification
097 */
098 public String getClassname()
099 {
100 return m_classname;
101 }
102
103 /**
104 * Return the service version.
105 *
106 * @return the version of interface
107 */
108 public Version getVersion()
109 {
110 return m_version;
111 }
112
113 /**
114 * Determine if specified service will match this service.
115 * To match a service has to have same name and must comply with version.
116 *
117 * @param other the other ServiceInfo
118 * @return true if matches, false otherwise
119 */
120 public boolean matches( final ServiceDescriptor other )
121 {
122 if( !m_classname.equals( other.m_classname ) )
123 {
124 return false;
125 }
126 else
127 {
128 return other.getVersion().complies( getVersion() );
129 }
130 }
131
132 /**
133 * Convert to a string of format name:version
134 *
135 * @return string describing service
136 */
137 public String toString()
138 {
139 return getClassname() + ":" + getVersion();
140 }
141
142 /**
143 * Compare this object with another for equality.
144 * @param other the object to compare this object with
145 * @return TRUE if the supplied object is a reference, service, or service
146 * descriptor that matches this objct in terms of classname and version
147 */
148 public boolean equals( Object other )
149 {
150 if( !( other instanceof ServiceDescriptor ) )
151 {
152 return false;
153 }
154
155 ServiceDescriptor service = (ServiceDescriptor) other;
156 if( !getClassname().equals( service.getClassname() ) )
157 {
158 return false;
159 }
160 else
161 {
162 return getVersion().equals( service.getVersion() );
163 }
164 }
165
166 /**
167 * Returns the cashcode.
168 * @return the hascode value
169 */
170 public int hashCode()
171 {
172 return getClassname().hashCode() ^ getVersion().hashCode();
173 }
174
175 private static final String parseClassname( final String spec )
176 throws NullPointerException
177 {
178 if( spec == null )
179 {
180 throw new NullPointerException( "spec" );
181 }
182
183 int index = spec.indexOf( "#" );
184 if( index == -1 )
185 {
186 return spec;
187 }
188 else
189 {
190 return spec.substring( 0, index );
191 }
192 }
193
194 private static final Version parseVersion( final String spec )
195 {
196 int index = spec.indexOf( "#" );
197 if( index == -1 )
198 {
199 return Version.parse( "1" );
200 }
201 else
202 {
203 String value = spec.substring( index + 1 );
204 return Version.parse( value );
205 }
206 }
207 }